package com.newlink.building.widget

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.*
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.*
import android.provider.MediaStore
import android.text.method.ScrollingMovementMethod
import android.util.Log
import android.view.*
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast
import androidx.core.app.NotificationCompat
import androidx.core.content.FileProvider
import com.newlink.building.R
import com.newlink.building.activities.Module_Phone_NotificationActivity
import com.newlink.building.utils.Module_Phone_EncryptUtils
import com.newlink.building.utils.Module_Phone_SettingUtil
import com.newlink.building.utils.http.Module_Phone_DownloadUtils
import java.io.File
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

/**
 * @Author: Jake
 * @Date: 2022/11/30
 * @Description: app升级使用
 */
class Module_Phone_UpdateDialog {

    class Builder(context: Context) : Module_Phone_BaseDialog.Builder<Builder>(context), View.OnClickListener {

        private val nameView: TextView? by lazy { findViewById(R.id.tv_update_name) }
        private val detailsView: TextView? by lazy { findViewById(R.id.tv_update_details) }
        private val progressView: ProgressBar? by lazy { findViewById(R.id.pb_update_progress) }
        private val updateView: TextView? by lazy { findViewById(R.id.tv_update_update) }
        private val closeView: TextView? by lazy { findViewById(R.id.tv_update_close) }

        private var apkFile: File? = null

        private var notificationManager: NotificationManager? = null

        private val notificationId = getContext().applicationInfo.uid

        private var downloadUrl: String? = null

        private var fileMd5: String? = null

        private var forceUpdate = false

        private var downloading = Module_Phone_SettingUtil.getDownloadStatus()

        private var downloadComplete = false

        init {
            setContentView(R.layout.update_dialog)
//            setAnimStyle(AnimAction.ANIM_BOTTOM)
            setCancelable(false)
            setCanceledOnTouchOutside(false)
            updateView?.setOnClickListener(this)
            closeView?.setOnClickListener(this)
            detailsView?.movementMethod = ScrollingMovementMethod()
        }

        fun setVersionName(name: CharSequence?): Builder = apply {
            nameView?.text = name
        }

        fun setUpdateLog(text: CharSequence?): Builder = apply {
            detailsView?.text = text
            detailsView?.visibility = if (text == null) View.GONE else View.VISIBLE
        }

        fun setForceUpdate(force: Boolean): Builder = apply {
            forceUpdate = force
            closeView?.visibility = if (force) View.GONE else View.VISIBLE
            setCancelable(!force)
        }

        fun setDownloadUrl(url: String?): Builder = apply {
            downloadUrl = url
        }

        fun setFileMd5(md5: String?): Builder = apply {
            fileMd5 = md5
        }

        override fun onClick(view: View) {
            if (view === closeView) {
                dismiss()
            } else if (view === updateView) {
                downloadApk()
            }
        }

        private fun installDownloadApk() {
//            val apkPath = getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)!!.absolutePath
//            val apkName = getContext().getString(R.string.app_name) + "_v" + nameView?.text.toString() + ".apk"
//            apkFile = File(apkPath, apkName)
            apkFile?.let {
                if (!it.exists()) {
                    return
                }
                val intent = Intent()
                intent.action = Intent.ACTION_VIEW

                val publicUri = FileProvider.getUriForFile(
                    getContext(),
                    getContext().getString(R.string.file_provider),
                    apkFile!!
                )

                intent.putExtra(MediaStore.EXTRA_OUTPUT, publicUri)
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                intent.setDataAndType(publicUri, "application/vnd.android.package-archive")

                getContext().startActivity(intent)
            }
        }

        @OptIn(DelicateCoroutinesApi::class)
        private fun downloadApk() {
            Module_Phone_SettingUtil.setDownloadStatus(true)
            // 设置对话框不能被取消
            setCancelable(false)
            notificationManager = getContext().getSystemService(NotificationManager::class.java)

            var channelId = ""
            // 适配 Android 8.0 通知渠道新特性
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val channel = NotificationChannel(
                    getContext().getString(R.string.update_notification_channel_id),
                    getContext().getString(R.string.update_notification_channel_name),
                    NotificationManager.IMPORTANCE_LOW
                )
                channel.enableLights(false)
                channel.enableVibration(false)
                channel.vibrationPattern = longArrayOf(0)
                channel.setSound(null, null)
                notificationManager?.createNotificationChannel(channel)
                channelId = channel.id
            }
            val notificationBuilder: NotificationCompat.Builder =
                NotificationCompat.Builder(getContext(), channelId)
                    // 设置通知时间
                    .setWhen(System.currentTimeMillis())
                    // 设置通知标题
                    .setContentTitle(getContext().getString(R.string.app_name))
                    // 设置通知小图标
                    .setSmallIcon(R.mipmap.ic_launcher)
                    // 设置通知大图标
                    .setLargeIcon(
                        BitmapFactory.decodeResource(
                            getContext().getResources(),
                            R.mipmap.ic_launcher
                        )
                    )
                    // 设置通知静音
                    .setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE)
                    // 设置震动频率
                    .setVibrate(longArrayOf(0))
                    // 设置声音文件
                    .setSound(null)
                    // 设置通知的优先级
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)

            // 创建要下载的文件对象
            val intent = Intent(getContext(), Module_Phone_NotificationActivity::class.java)

            val apkPath =
                getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)!!.absolutePath
            val apkName =
                getContext().getString(R.string.app_name) + "_v" + nameView?.text.toString() + ".apk"

            // download
            Module_Phone_DownloadUtils.get()?.download(
                downloadUrl!!, apkPath, apkName,
                object : Module_Phone_DownloadUtils.OnDownloadListener {

                    override fun onDownloadSuccess(file: File?) {
                        Log.e("jake", " [UpdateDialog] -> Download = Success :$file")
                        apkFile = File(
                            apkPath,
                            apkName
                        )
                        Log.e("jake", "下载文件 MD5 is " + Module_Phone_EncryptUtils.getMD5String(apkFile!!))
                        if (apkFile!!.exists() && (Module_Phone_EncryptUtils.getMD5String(apkFile!!)
                                .equals(fileMd5))
                        ) {

                            GlobalScope.launch(Dispatchers.Main) {
                                downloadComplete = true
                                notificationBuilder.setContentTitle("下载完成")
                                intent.putExtra(Module_Phone_NotificationActivity.APP_PATH, apkPath)
                                intent.putExtra(Module_Phone_NotificationActivity.APP_NAME, apkName)

                                val contentIntent = PendingIntent.getActivity(
                                    getContext(),
                                    0,
                                    intent,
                                    PendingIntent.FLAG_MUTABLE
                                )
                                notificationBuilder.setContentIntent(contentIntent)
                                notificationManager?.notify(
                                    notificationId,
                                    notificationBuilder.build()
                                )
                                installDownloadApk()
                            }
                        } else {
                            Log.e("jake", " [UpdateDialog] -> Success :找不到文件")
                        }
                        Module_Phone_SettingUtil.setDownloadStatus(false)
                    }

                    override fun onDownloading(progress: Int) {
                        notificationBuilder.setContentTitle("下载进行中")
                        notificationBuilder.setContentText("当前下载进度 $progress%")
                        notificationManager?.notify(notificationId, notificationBuilder.build())
                        Log.e("jake", " [UpdateDialog] -> Downloading :$progress")
                    }

                    override fun onDownloadFailed(e: Exception?) {
                        notificationBuilder.setContentTitle("下载失败")
                        Log.e("jake", " [UpdateDialog] -> Download = Failed :$e")
                        downloadComplete = true
                        Module_Phone_SettingUtil.setDownloadStatus(false)
                    }
                }
            )

            dismiss()
        }

        override fun show() {

            if (Module_Phone_SettingUtil.getDownloadStatus()) {
                Toast.makeText(getContext(), R.string.update_processing, Toast.LENGTH_SHORT).show()
                return
            }
            super.show()
        }

        private fun installApk() {
            getContext().startActivity(getInstallIntent())
        }

        private fun getInstallIntent(): Intent {
            val intent = Intent()
            intent.action = Intent.ACTION_VIEW
            val uri: Uri?
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                val authorityStr = getContext().packageName + ".provider"
                val authorityStr1 = getContext().packageName + ".provider"
                uri = FileProvider.getUriForFile(getContext(), authorityStr1, apkFile!!)
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
            } else {
                uri = Uri.fromFile(apkFile)
            }
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
            intent.setDataAndType(uri, "application/vnd.android.package-archive")
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            return intent
        }
    }
}
